package gw.com.android.ui.me;

import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.annotation.NonNull;
import android.text.Editable;
import android.text.InputFilter;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

import com.gwtsz.gts2.hx.R;

import org.json.JSONObject;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import butterknife.BindView;
import butterknife.OnClick;
import gw.com.android.app.AppContances;
import gw.com.android.app.AppMain;
import gw.com.android.app.GTConfig;
import gw.com.android.model.ConfigType;
import gw.com.android.model.ConfigUtil;
import gw.com.android.model.DataManager;
import gw.com.android.ui.BaseActivity;
import gw.com.android.ui.dialog.SelectPhotoDialog;
import gw.com.android.ui.views.PickImageView;
import gw.com.android.ui.views.PickedImageItem;
import gw.com.android.utils.ImageUtil;
import gw.com.android.utils.ThreadPool;
import gw.com.jni.library.terminal.GTSConst;
import okhttp3.Call;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import www.com.library.app.Logger;
import www.com.library.dialog.ToastPopWindow;
import www.com.library.util.NetworkMonitor;
import www.com.library.util.PermissionUtil;

/**
 * 意见反馈
 *
 * @author jett
 * @since 2017-10-17.
 */
public class FeedbackActivity extends BaseActivity {

    private final String TAG = "feedback";
    public static final int REQUEST_PICK = 22;
    public static final int REQUEST_CAMERS = 23;
    public static final int REQUEST_PREVIEW = 24;
    public static final String FEED_PATH = "feed_path";

    private static final int MAX_IMAGE = 3;//可添加的图片最大数量
    private static final int MAX_CONTENT = 200;// 问题描述最大字数
    private static final long MAX_FILE_SIZE = 500 * 1024; // 500kb

    @BindView(R.id.piv_add_photo)
    PickImageView piv;
    @BindView(R.id.et_content)
    EditText content;
    @BindView(R.id.et_phone_number)
    EditText phone;
    @BindView(R.id.tv_phone_number)
    TextView phoneTitle;
    @BindView(R.id.tv_word_count)
    TextView counter;

    private final ArrayList<String> images = new ArrayList<>(MAX_IMAGE);
    private String takePhotoPath;
    private PermissionUtil mAccessCameraPermission;
    private boolean loading = false;

    @Override
    protected int getLayoutView() {
        return R.layout.activity_feedback;
    }

    @Override
    protected void initLayoutView() {
        mTitleBar.setAppTitle(R.string.feedback_title);
        if (GTConfig.instance().getAccountType() != GTConfig.ACC_TYPE_GUEST) {
            phone.setVisibility(View.GONE);
            phoneTitle.setVisibility(View.GONE);
        }
        content.setFilters(new InputFilter[]{new InputFilter.LengthFilter(MAX_CONTENT)});
        content.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }

            @Override
            public void afterTextChanged(Editable s) {
                int length = s.toString().length();
                counter.setText(String.format(Locale.getDefault(), "%d/%d", length, MAX_CONTENT));
            }
        });
        piv.setMaxCount(MAX_IMAGE);
        piv.setOnPickImageListener(new PickImageView.OnPickImageListener() {
            @Override
            public void onAdd(PickImageView piv) {
                showSelectDialog();
            }

            @Override
            public void onRemove(PickImageView piv, PickedImageItem item, String resource) {
                images.remove(resource);
            }

            @Override
            public void onPhoto(PickImageView piv, int index) {
                Intent intent = new Intent(FeedbackActivity.this, PreviewActivity.class);
                intent.putStringArrayListExtra(PreviewActivity.IMAGE_PATH, new ArrayList<String>(images));
                intent.putExtra(PreviewActivity.IMAGE_INDEX, index);
                startActivityForResult(intent, REQUEST_PREVIEW);
            }
        });
    }

    @Override
    protected void initViewData() {
        String path = getIntent().getStringExtra(FEED_PATH);
        if (!TextUtils.isEmpty(path)) {
            images.add(path);
            piv.add(path);
        }
        PhoneNumber.getInstance().acquireAsync(null);
    }

    private void showSelectDialog() {
        int residual = MAX_IMAGE - images.size();
        new SelectPhotoDialog(FeedbackActivity.this, residual).selectListener(new SelectPhotoDialog.OnSelectListener() {
            @Override
            public void onAlbum(SelectPhotoDialog dialog, View view) {
                album();
            }

            @Override
            public void onCamera(SelectPhotoDialog dialog, View view) {
                requestCameraPermission();
            }
        }).show();
    }

    private void album() {
        Intent intent = new Intent(getApplication(), AlbumActivity.class);
        intent.putStringArrayListExtra(AlbumActivity.PICKED_LIST, new ArrayList<>(images));
        startActivityForResult(intent, REQUEST_PICK);
    }

    private void requestCameraPermission() {
        mAccessCameraPermission = new PermissionUtil();
        mAccessCameraPermission.requestPermission(this, Manifest.permission.CAMERA, AppContances.REQUEST_PERMISSION_ACCESS_CAMERA, new PermissionUtil.OnRequestPermissionResult() {
            @Override
            public void onGranted() {
                launchCamera();
            }

            @Override
            public void onRefused() {
            }
        });
    }

    private void launchCamera() {
        try {
            takePhotoPath = ImageUtil.getNewPhotoPath();
            Intent mSourceIntent = ImageUtil.takeBigPicture(this, takePhotoPath);
            startActivityForResult(mSourceIntent, REQUEST_CAMERS);
        } catch (Exception ignore) {
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (mAccessCameraPermission != null) {
            mAccessCameraPermission.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode != Activity.RESULT_OK) {
            return;
        }
        if (requestCode == REQUEST_PICK && data != null) {
            images.clear();
            piv.clear();
            ArrayList<String> list = data.getStringArrayListExtra("result");
            if (list != null && !list.isEmpty()) {
                images.addAll(list);
                piv.add(images);
            }
        } else if (requestCode == REQUEST_CAMERS) {
            if (images.size() >= MAX_IMAGE) {
                return;
            }
            if (TextUtils.isEmpty(takePhotoPath)) {
                return;
            }
            images.add(takePhotoPath);
            piv.add(takePhotoPath);
            takePhotoPath = null;
        } else if (requestCode == REQUEST_PREVIEW && data != null) {
            ArrayList<String> list = data.getStringArrayListExtra("data");
            if (list != null && !list.isEmpty()) {
                images.removeAll(list);
                piv.remove(list);
            }
        }
    }

    @OnClick(R.id.tv_submit)
    public void submit() {
        Logger.i(TAG, "submit");
        if (!NetworkMonitor.isNetworkReady(this)) {
            toast(R.string.feedback_network_error);
            return;
        }
        final String content = this.content.getText().toString();
        if (TextUtils.isEmpty(content)) {
            toast(R.string.feedback_content_empty);
            return;
        }
        if (loading) {
            Logger.i(TAG, "submit.a task is running,please submit after previous task response.");
            return;
        }
        loading = true;
        showLoading();
        String phoneNum = this.phone.getText().toString();
        if (TextUtils.isEmpty(phoneNum)) {
            phoneNum = PhoneNumber.getInstance().get();
            if (phoneNum == null) {
                phoneNum = "";
            }
        }
        List<String> paths = getUploadImagesPath(new ArrayList<String>(images));
        Logger.i(TAG, "submit .. start");
        ThreadPool.getInstance().submit(new LoadTask(content, phoneNum, paths));
    }

    private class LoadTask implements Runnable {
        private final String content;
        private final String phoneNum;
        private final List<String> imagePaths;

        LoadTask(String content, String phoneNum, List<String> paths) {
            this.content = content;
            this.phoneNum = phoneNum;
            this.imagePaths = paths;
        }

        @Override
        public void run() {
            Logger.i(TAG, "submit task run..");
            if (FeedbackActivity.this.isFinishing()) {
                Logger.i(TAG, "activity is finishing...");
                return;
            }
            OkHttpClient client = new OkHttpClient.Builder().build();
            MultipartBody.Builder builder = new MultipartBody.Builder()
                    .setType(MultipartBody.FORM)
                    .addFormDataPart("content", content)
                    .addFormDataPart("phone", phoneNum)
                    .addFormDataPart("login", DataManager.instance().mAccount.getString(GTSConst.JSON_KEY_NAME));

            List<String> formatedPaths = getUploadImagesPath(imagePaths);
            if (formatedPaths != null && !formatedPaths.isEmpty()) {
                int counter = 0;
                for (String path : formatedPaths) {
                    RequestBody rBody = RequestBody.create(MediaType.parse("application/octet-stream"), new File(path));
                    builder.addFormDataPart("file_" + counter++, getFileName(path), rBody);
                }
            }
            String url = ConfigUtil.instance().getUrlPath(ConfigType.FEEDBACK_TAG);
            final Request request = new Request.Builder().url(url).post(builder.build()).build();
            Call call = client.newCall(request);
            try {
                Response response = call.execute();
                Logger.i(TAG, "submit . get an response.");
                loading = false;
                if (response != null && response.isSuccessful()) {
                    Logger.i(TAG, "submit . response success");
                    String body = response.body().string();
                    if (!TextUtils.isEmpty(body)) {
                        int result = new JSONObject(body).optInt("ret");
                        Logger.i(TAG, "submit . response ret = " + result);
                        if (result == 200) {
                            hideLoading();
                            toast(R.string.feedback_submit_success);
                            finish();
                            return;
                        }
                    }
                }
            } catch (Exception e) {
                Logger.i(TAG, "submit . an error occured.");
                loading = false;
                Logger.e(TAG, e);
            }
            toast(R.string.feedback_submit_error);
            hideLoading();
        }
    }

    private void toast(final int resId) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                new ToastPopWindow(FeedbackActivity.this, AppMain.getAppString(resId)).show();
            }
        });
    }

    private List<String> getUploadImagesPath(List<String> paths) {
        if (paths == null || paths.isEmpty()) {
            return null;
        }
        List<String> result = new ArrayList<>();
        for (String path : paths) {
            if (TextUtils.isEmpty(path)) {
                continue;
            }
            File file = new File(path);
            if (file.exists()) {
                long size = file.length();
                if (size > MAX_FILE_SIZE) {
                    path = compress(file);
                }
                result.add(path);
            }
        }
        return result;
    }

    private String compress(File file) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inSampleSize = (int) Math.ceil(file.length() / MAX_FILE_SIZE);
        Bitmap bitmap = BitmapFactory.decodeFile(file.getPath(), options);

        File outFile = new File(getExternalCacheDir(), getFileName(file.getPath()));
        try {
            FileOutputStream out = new FileOutputStream(outFile);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
        } catch (FileNotFoundException e) {
            Logger.e(TAG, e);
        }
        return outFile.getPath();
    }

    private String getFileName(String path) {
        if (!TextUtils.isEmpty(path)) {
            int index = path.lastIndexOf("/");
            if (index > 0) {
                return path.substring(index + 1, path.length());
            }
        }
        return "";
    }

}
